package com.feonix.common.util;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Locale;

import javax.servlet.http.HttpServletRequest;

import org.apache.axis2.context.MessageContext;
import org.apache.axis2.transport.http.HTTPConstants;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.aop.framework.Advised;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;

/**
 * 
 * @CopyRight (c)1993-2017
 * @Project m-complat-common
 * @Comments springUtil，此类获取spring的一系列配置或者是在service中获取request的请求等等，用于系统级的信息封装
 * @NameSpace com.feonix.common.util
 * @Author Feonixzw
 * @CreateDate 2017年11月8日
 */
public class SpringUtil implements ApplicationContextAware {

	private static final Log logger = LogFactory.getLog(SpringUtil.class);
	private static ApplicationContext applicationContext;

	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		this.applicationContext = applicationContext;
	}

	/**
	 * 获取想要的bean
	 * 
	 * @param beanClass
	 * @return
	 */
	public static <T> T getBean(Class<T> beanClass) {
		return applicationContext.getBean(beanClass);
	}

	/**
	 * 获取想要的beans
	 * 
	 * @param beanClass
	 * @return
	 */
	public static <T> Collection<T> getBeans(Class<T> beanClass) {
		Collection<T> collection = applicationContext.getBeansOfType(beanClass).values();
		ArrayList<T> arrayList = new ArrayList<T>();
		if (collection != null) {
			arrayList.addAll(collection);
			sortBeans(arrayList);
		}
		return arrayList;
	}

	/**
	 * bean 按照sort排序
	 * 
	 * @param beans
	 */
	public static <T> void sortBeans(List<T> beans) {
		if (beans != null)
			Collections.sort(beans, AnnotationAwareOrderComparator.INSTANCE);
	}

	/**
	 * 获取想要的bean
	 * 
	 * @param beanId
	 *            spring配置文件中bean 的 id
	 * @return
	 */
	public static Object getBean(String beanId) {
		return applicationContext.getBean(beanId);
	}

	/**
	 * 获取想要的bean
	 * 
	 * @param beanId
	 *            spring配置文件中bean 的 id
	 * @param clazz
	 *            类型
	 * @return
	 */
	public static <T> T getBean(String beanId, Class<T> clazz) {
		T t = null;
		try {
			t = applicationContext.getBean(beanId, clazz);
		} catch (Exception e) {
			logger.error("getBean line91 error:", e);
		}
		return t;
	}

	/**
	 * 获得代理对象的bean
	 * 
	 * @param proxy
	 * @param targetClass
	 * @return
	 */
	public static <T> T getTargetObject(Object proxy, Class<T> targetClass) {
		Object object = null;
		try {
			if (AopUtils.isJdkDynamicProxy(proxy)) {
				object = ((Advised) proxy).getTargetSource().getTarget();
				return (T) object;
			}
			object = proxy;
		} catch (Exception exception) {
			logger.error("getTargetObject error", exception);
		}
		return (T) object;
	}

	/**
	 * 获得本地化信息
	 * 
	 * @param key
	 * @return
	 */
	public static String getMessage(String key) {
		return getMessage(key, new Object[0]);
	}

	/**
	 * 获得本地化信息
	 * 
	 * @param key
	 * @param param
	 * @return
	 */
	public static String getMessage(String key, Object... param) {
		return getLocaleMessage(key, param);
	}

	/**
	 * 获得本地化信息
	 * 
	 * @param key
	 * @param param
	 * @return
	 */
	private static String getLocaleMessage(String key, Object... param) {
		HttpServletRequest httpServletRequest = getRequest();
		Locale locale = null;
		if (httpServletRequest != null) {
			locale = ((SessionLocaleResolver) getBean(SessionLocaleResolver.class)).resolveLocale(getRequest());
		}
		if (locale == null) {
			locale = Locale.getDefault();
		}
		String str = applicationContext.getMessage(key, param, locale);
		return str;
	}

	public static ApplicationContext getApplicationContext() {
		return applicationContext;
	}

	/**
	 * 封装了request的请求，用于直接在没有传HttpServletRequest对象的时候，获取该请求
	 * 
	 * @return
	 */
	public static HttpServletRequest getRequest() {
		ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder
				.getRequestAttributes();
		HttpServletRequest httpServletRequest = null;
		if (servletRequestAttributes != null) {
			httpServletRequest = servletRequestAttributes.getRequest();
		} else {
			MessageContext messageContext = MessageContext.getCurrentMessageContext();
			if (messageContext != null) {
				httpServletRequest = (HttpServletRequest) messageContext
						.getProperty(HTTPConstants.MC_HTTP_SERVLETREQUEST);
			}
		}
		return httpServletRequest;
	}

}
